package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.UserLike;
import com.tanhua.domain.mongo.Visitor;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class VisitorApiImpl implements VisitorApi {

    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 添加访客记录
     *
     * @param visitor
     */
    @Override
    public void add(Visitor visitor) {
        mongoTemplate.insert(visitor);
    }

    /**
     * 通过用户id查询最近的4位访客
     *
     * @param userId
     * @return
     */
    @Override
    public List<Visitor> findLast4Visitors(Long userId) {
        //1. 查询访客表
        //1.1 构建查询条件
        Query query = new Query(Criteria.where("userId").is(userId));
        //1.2 按时间降序
        query.with(Sort.by(Sort.Order.desc("date")));
        //1.3 设置分页参数（前4条）
        query.skip(0).limit(4);
        //1.4 查询获取访客列表
        List<Visitor> visitorList = mongoTemplate.find(query, Visitor.class);
        if(!CollectionUtils.isEmpty(visitorList)) {
            //2. 查询登录用户与访客的缘分值
            List<Long> visitorUserIds = visitorList.stream().map(Visitor::getVisitorUserId).collect(Collectors.toList());
            Query recommendUserQuery = new Query(Criteria.where("toUserId").is(userId)
                    .and("userId").in(visitorUserIds));
            List<RecommendUser> recommendUserList = mongoTemplate.find(recommendUserQuery, RecommendUser.class);
            // 转成map key=访客的id, value=缘分值
            Map<Long, Double> userScoreMap = recommendUserList.stream()
                    .collect(Collectors.toMap(RecommendUser::getUserId, RecommendUser::getScore));
            // 给每个访客数据设置缘分值
            visitorList.forEach(v->v.setScore(userScoreMap.get(v.getVisitorUserId())));
        }
        //3. 返回
        return visitorList;
    }

    /**
     * 查询谁看过我
     *
     * @param userId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult findPageByUserId(Long userId, Long page, Long pageSize) {
        //1. 查询访客表
        //1.1 构建查询条件
        Query query = new Query(Criteria.where("userId").is(userId));
        long total = mongoTemplate.count(query, Visitor.class);
        List<RecommendUser> recommendUserListSort = new ArrayList<>();
        if (total > 0) {
            //1.2 按时间降序
            query.with(Sort.by(Sort.Order.desc("date")));
            //1.3 设置分页参数（前4条）
            query.skip((page-1)*pageSize).limit(pageSize.intValue());
            //1.4 查询获取访客列表
            List<Visitor> visitorList = mongoTemplate.find(query, Visitor.class);
            if(!CollectionUtils.isEmpty(visitorList)) {
                //2.再查登录用户与访客的缘分
                List<Long> visitorIds = visitorList.stream().map(Visitor::getVisitorUserId).collect(Collectors.toList());
                Query recommendUserQuery = new Query(Criteria.where("toUserId").is(userId)
                        .and("userId").in(visitorIds));
                List<RecommendUser> recommendUserList = mongoTemplate.find(recommendUserQuery, RecommendUser.class);
                // 转成map key=访客的id, value=RecommendUser
                Map<Long, RecommendUser> recommendUserMap = recommendUserList.stream()
                        .collect(Collectors.toMap(RecommendUser::getUserId, ru -> ru));
                // 转成保留顺序的结果集， 因为mongodb查询缘分时，会导致顺序发生变化。
                for (Visitor visitor : visitorList) {
                    RecommendUser ru = recommendUserMap.get(visitor.getVisitorUserId());
                    recommendUserListSort.add(ru);
                }
            }
        }
        //3. 返回
        return PageResult.pageResult(page,pageSize,recommendUserListSort, total);
    }

}
